home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / timing.swg < prev    next >
Text File  |  1994-09-22  |  11KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00004                                                                           1      08-24-9413:21ALL                      KAI ROHRBACHER           Dpmi HiRes Timer         SWAG9408    ü⌐òk    40     «u   πUNIT asytimer;π{Purpose  : High resolution timer which runs asynchronous to the     }π{           rest of the program                                      }π{Author   : Kai Rohrbacher, kai.rohrbacher@logo.ka.sub.org           }π{Language : BorlandPascal 7.0 }π{Date     : 26.06.1994        }π{Remarks  : - Runs both in real- and protected mode.                 }π{           - Only available on AT-style machines or better (uses    }π{             real time clock services)                              }π{           - Will "fall through" on PC's transparently: behaves as  }π{             if time ran off immediately}ππINTERFACEππVAR TimeFlag:^BYTE;ππFUNCTION ATClockAvailable:BOOLEAN;πPROCEDURE SetCycleTime(microseconds:LONGINT);πFUNCTION TimeOver:BOOLEAN;π  INLINE($C4/$1E/TimeFlag/   {LES BX,TimeFlag}π         $26/$8A/$07/        {MOV AL,ES:[BX] }π         $B1/$07/            {MOV CL,7 }π         $D2/$E8);           {SHR AL,CL}πPROCEDURE Trigger;ππIMPLEMENTATIONππUSES CRT;ππ{$IFDEF DPMI}πTYPE Treg=RECORD  {stuff for that dumb DPMI-server}π           CASE BYTE OFπ            0:(LoLo,LoHi,HiLo,HiHi:BYTE);π            1:(Lo16,Hi16:WORD);π          END;π     Tregisters32=π       RECORDπ         EDI,ESI,EBP,junk32,EBX,EDX,ECX,EAX:Treg;π         Flags32,ES,DS,FS,GS,IP,CS,SP,SS:WORDπ       END;πVAR regs32:Tregisters32;ππ FUNCTION EmulateInt(IntNr:BYTE; VAR regs32:Tregisters32):BOOLEAN;π ASSEMBLER; {emulate real mode interrupt IntNr with registers regs32}π ASMπ   MOV AX,300h   {emulate INT}π   XOR BH,BH     {no A20 gate reset, please}π   MOV BL,IntNr  {INT to emulate}π   XOR CX,CX     {no parameter passing via PM stack}π   LES DI,regs32 {pointer to register set}π   INT 31h       {go for it}π   CMC           {carry flag set if error, reflect this}π   MOV AX,0      {as a BOOLEAN value: return TRUE if C=0}π   ADC AX,AX     {and FALES otherwise}π END;π{$ENDIF}ππVAR CycleTimeLo16,CycleTimeHi16:WORD;π    IsAT:BYTE;ππ{$IFDEF DPMI}πFUNCTION ATClockAvailable:BOOLEAN; {protected mode function}πBEGINπ TimeFlag^:=0;             {reset flag}π FillChar(regs32,SizeOf(regs32),0);π regs32.ECX.Lo16:=0;π regs32.EDX.Lo16:=1;       {trigger flag after 1us}π regs32.ES      :=$40;     {_segment_ address of Timeflag}π regs32.EBX.Lo16:=Ofs(TimeFlag^); {offset part = $F0}π regs32.EAX.Lo16:=$8300;ππ IF NOT EmulateInt($15,regs32)π  THEN WRITELN('Something went wrong in the INT-emulation!?');ππ Delay(1); {INT-emulation went ok, look for timer event:}π           {wait 1000us, so event must have happened:}π {Flag now should have been set to $80:}π ATClockAvailable:=TimeFlag^=$80;πEND;ππ{$ELSE}ππFUNCTION ATClockAvailable:BOOLEAN; {real mode function}πBEGINπ TimeFlag^:=0;             {reset flag}π IF Test8086<>0  {is it at least an AT?}π  THEN ASM {yes, have a closer look:}π         STIπ         XOR CX,CX       {trigger after 1us}π         MOV DX,1π         LES BX,TimeFlag {set Flag to $80 after this time}π         MOV AX,8300h    {run asynchron to rest of program}π         INT 15h         {go!}π       END;π Delay(1);               {wait a 1000us}π ATClockAvailable:=TimeFlag^=$80 {Flag=$80, if it worked}πEND;π{$ENDIF}ππPROCEDURE SetCycleTime(microseconds:LONGINT);πBEGINπ TimeFlag^:=$80;π CycleTimeHi16:=microseconds SHR 16;π CycleTimeLo16:=microseconds AND $FFFF;π IF (microseconds<>0) AND ATClockAvailableπ  THEN IsAT:=0     {ja, Zeitüberwachung soll benutzt werden  }π  ELSE IsAT:=$80   {nein, keine möglich oder nicht gewünscht }πEND;ππPROCEDURE Trigger;π{starts timer, which must have previously been set by SetCycleTime()}πBEGINπ IF IsAT<>0 THEN EXIT; {jmp out, if timer services unavailable}π TimeFlag^:=0;π{$IFDEF DPMI}π regs32.ECX.Lo16:=CycleTimeHi16;π regs32.EDX.Lo16:=CycleTimeLo16;  {trigger flag after t us}π regs32.ES      :=$40;            {_segment_ address of Timeflag}π regs32.EBX.Lo16:=Ofs(TimeFlag^); {offset part = $F0}π regs32.EAX.Lo16:=$8300;ππ IF NOT EmulateInt($15,regs32)π  THEN WRITELN('Something went wrong in the INT-emulation!?');π{$ELSE}πASMπ  MOV CX,CycleTimeHi16π  MOV DX,CycleTimeLo16π  LES BX,TimeFlag {set Flag to $80 after this time}π  MOV AX,8300h    {run asynchron to rest of program}π  INT 15h         {go!}πEND;π{$ENDIF}πEND;ππBEGINπ TimeFlag:=Ptr(Seg0040,$F0); {available byte in 1st MB}π SetCycleTime(0)πEND.ππ____ππPROGRAM TestUnit_asytimer;π{Kai Rohrbacher, kai.rohrbacher@logo.ka.sub.org}πUSES asytimer;πCONST wait:LONGINT=5000000; {trigger time in us -> 5sec}ππ PROCEDURE SomeThing;π CONST s:ARRAY[0..3] OF CHAR='\|/-';π       help:BYTE=0;π BEGIN WRITE(s[help]+^H); help:=(help+1) AND 3 END;ππBEGINπ IF ATClockAvailableπ  THEN WRITELN('INT15h-timer-routine available!')π  ELSE WRITELN('INT15h-timer-routine doesn''t work!');ππ SetCycleTime(wait);π WRITELN('Between the following 2 bells, there should be a delay of ',π         wait,' microseconds');π Trigger;    {wait 5s = 5000ms}π WRITE(#7);π WHILE NOT TimeOver DO SomeThing;π WRITELN(#7'Done!');πEND.π                                                                               2      08-24-9413:44ALL                      PETE ROCCA               multitasking program     SWAG9408    /äMü    16     «u   {πYC> Does anyone got any unit/code on giving up time slice under DV or OS/2?πHere they are for DOS, Windows, OS/2, DV and DoubleDos.  You will needπto detect the enviroment first (although none should make the systemπhang if it's the wrong enviroment, just be ignored)  The key to goodπidle release is finding the right spots to put them.  I have gotten myπdoor making unit that I created to about 97% idle during pauses and 93%πidle while waiting for keyboard input (with no delay in response - muchπbetter than the typical 12% idle pauses and 8% idle keyboard waits)πHere is how... }ππProcedure Sleep(Seconds: Word);πVarπ  H,M,S,T,Last: Word;πBeginπ  If Seconds = 0 Then Exit;π  If Seconds > 999 Then Seconds := Seconds DIV 1000;π  {incase of caller is thinking milliseconds}ππ  GetTime(H,M,Last,T);π  Repeatπ    Repeatπ      GetTime(H,M,S,T);π      TimerSlice;π      TimerSlice;π    Until S <> Last;π    Last := S;π    Dec(Seconds);π  Until Seconds = 0;πEnd;ππFunction GetChar: Char;πVarπ  Counter, Span: Byte;π  Done: Boolean;πBeginπ  Span := 0;π  Done := False;π  Repeatπ    Inc(Counter);π    If Counter > Span Thenπ      Beginπ        Counter := 0;π        If IsChar Then Done := Trueπ        Else If Span < 50 Then Inc(Span);π      Endπ    Else TimerSlice;π  Until Done;π  If KeyPressedExtended Then GetChar := Readkeyπ  Else GetChar := RxChar;πEnd;ππProcedure TimerSlice;πBeginπ  Case SystemEnviroment Ofπ    DOS4:;π    DOS5,π    WINDOWS,π    OS2: Asmπ           MOV AX,$1680π           INT $2Fπ         End;π    DV: Asmπ          MOV AX,$1000π          INT $15π        End;π    DOUBLEDOS: Asmπ                 MOV AX,$EE01π                 INT $21π               End;π  End;πEnd;ππThis is released as public domain, however if you are using it, I'dπappreciate a PRIVATE NETMAIL message to me at 1:2401/123 letting meπknow.ππThanksππPete RoccaπMultiboard Communications Centre @ 1:2401/123π                     3      08-24-9417:52ALL                      GAYLE DAVIS              A good Timer unit        SWAG9408    ß'╦R    19     «u   πUNIT Timer;πINTERFACEππTYPEπ  tTimerObject = objectπ    TimerTicks : LONGINT;π    MaxSeconds : LONGINT;π    PROCEDURE Start(Amount : LONGINT);π    FUNCTION  ElapsedSeconds : LONGINT;π    FUNCTION  Remaining : LONGINT;π    FUNCTION  Expired : BOOLEAN;π    FUNCTION  PrintableTimer(Tics : LONGINT) : STRING;π  END;ππIMPLEMENTATIONπVARπ  TicksSinceMidnight : LONGINT ABSOLUTE $0040 : $006c;ππ  PROCEDURE tTimerObject.Start(Amount : LONGINT);π  BEGINπ    TimerTicks := TicksSinceMidnight;π    MaxSeconds := Amount;π  END;ππ  FUNCTION tTimerObject.ElapsedSeconds : LONGINT;  { elapsed time in seconds }π  CONSTπ    TicksPerDay = 1573040;π    TicksPerSecond = 18.20648;π  VARπ    ElapsedTicks : LONGINT;ππ  BEGINπ    ElapsedTicks := TicksSinceMidnight;π    IF (ElapsedTicks >= TimerTicks) THENπ      ElapsedTicks := ElapsedTicks - TimerTicksπ    ELSE      { Midnight rollover occurred }π      ElapsedTicks := TicksPerDay - TimerTicks + ElapsedTicks;π    ElapsedSeconds := ROUND (ElapsedTicks / TicksPerSecond);π  END;ππ  FUNCTION tTimerObject.Expired : BOOLEAN;  { Has this timer expired ?? }π  BEGINπ  Expired := (ElapsedSeconds > MaxSeconds);π  END;ππ  FUNCTION tTimerObject.Remaining : LONGINT;  { How many seconds remain? }π  BEGINπ  IF Expired THEN Remaining := 0 ELSEπ     Remaining := MaxSeconds - ElapsedSeconds;π  END;ππ  FUNCTION tTimerObject.PrintableTimer(Tics : LONGINT) : STRING;π  { return a printable time string }ππ    VARπ      S, T : STRING;π      Hour, Min, Sec, Time : LONGINT;π      i : INTEGER;ππ    BEGINπ    Hour := (Tics div 3600);π    Min  := (Tics div 60);π    Sec  := Tics - (Min * 60);π    STR(Min : 2, T);π    IF T[1] = #32 THEN T[1] := '0';π    S := T + ':';π    STR(Sec : 2, T);π    IF T[1] = #32 THEN T[1] := '0';π    S := S + T;π    PrintableTimer := S;π    END;πEND.ππ{ ----------------------------   DEMO   ----------------------- }ππusesπ  CRT, Timer;πvarπ  t : tTimerObject;ππbeginπ  ClrScr;π  t.Start(10);  { set a 10 second timer }π  GoToXY(1,1); Write(t.TimerTicks);π  repeatπ  GoToXY(1,2); Write(t.PrintableTimer(t.Remaining));π  GoToXY(1,3); Write(t.PrintableTimer(t.ElapsedSeconds));π  until (t.Expired);  { wait until it expires }π  Readkey;πend.π                                                                                                                    4      08-25-9409:12ALL                      STEVE ROGERS             Clock Ticks              SWAG9408    É∩α╠    8      «u   {πPN>Hi, Steve. I know this has been asked before, but am thinkingπ  >of using TicksSinceMidnight which is at memory location $0040:006Cπ  >as you say. Ny question is to what kind of type (size) variable shouldπ  >I assign this to, and how many bytes are reserved for this number?π  >$0040:006C ..  $0040:006D  ????π  >word? longint? integer?π                                           .π  60 * 60 * 24 = 86400 seconds per day.   . .  a longint is needed.π}π  varπ    TickSinceMidnight : longint ABSOLUTE $0040:$006c;π{π  BTW, that second $ is important :)πππ  >I appreciate your help. I'm going to try to get a 10ths secondsπ  >counter going by test-running the number of ticks in a second. Or wordsπ  >to that effect.ππ  There are approximately 18.2 ticks per second (thanks, Spock :)π}π